package com.chezai.client.server.codec;

import com.chezai.client.server.util.ChannelUtil;
import com.jx.driving.message.Message;
import com.jx.driving.protocol.terminal.codec.Codec;
import com.jx.driving.protocol.terminal.codec.TerminalHeadCodec;

import java.io.ByteArrayOutputStream;
import java.util.List;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageCodec;
import io.netty.util.Attribute;
import io.netty.util.AttributeKey;

/**
 * 消息头解析
 *
 * @author shenliuyang
 *         <p>
 *         2016年8月12日下午3:14:56
 */
public class NettyTerminalHeadCodec extends ByteToMessageCodec<Message> {

    private Codec codec = new TerminalHeadCodec();

    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
        byte[] content = (byte[]) codec.encode(ChannelUtil.getChannel(ctx.channel()), msg);
        out.writeBytes(content);
    }

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        ByteArrayOutputStream buf = byteBuffer(ctx.channel());
        while (in.isReadable()) {
            byte b = in.readByte();
            buf.write(b);
            // 字节不是0x7e就代表不是开始或结尾, buf的位置如果是1那么代表开头.反正结尾
            if (b != 0x7e || buf.size() == 1) {
                continue;
            }
            Object obj = codec.decode(ChannelUtil.getChannel(ctx.channel()), buf.toByteArray());
            buf.reset();
            if (obj == null) {
                continue;
            }
            Message msg = (Message) obj;
            out.add(msg);
        }
    }

    public ByteArrayOutputStream byteBuffer(Channel channel) {
        AttributeKey<ByteArrayOutputStream> key = AttributeKey.valueOf("key");
        Attribute<ByteArrayOutputStream> attribute = channel.attr(key);
        if (attribute.get() == null) {
            attribute.set(new ByteArrayOutputStream(4096));
        }
        return attribute.get();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//		Log.e("head codec","head codec 发生错误" ,cause);
    }
}
